package org.wattdepot.cli.command;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.StringTokenizer;
import java.util.TreeMap;
import java.util.Map.Entry;

import org.wattdepot.client.BadXmlException;
import org.wattdepot.client.MiscClientException;
import org.wattdepot.client.NotAuthorizedException;
import org.wattdepot.client.ResourceNotFoundException;
import org.wattdepot.client.WattDepotClient;
import org.wattdepot.resource.source.jaxb.Source;

/**
 * Implements the FuelTypeCommand handler.
 * 
 * @author Yichi Xu
 *
 */
public class FuelTypeCommand extends WattDepotCliCommand {
  /**
   * Creates an instance of the FuelType command handler.
   * 
   * @param client An instance of the WattDepotClient.
   */
  public FuelTypeCommand(WattDepotClient client) {
    super(client);
  }
  
  /**
   * List the fuel type given a source name.
   * Returns an error message if one occurs.
   * 
   * @param command The command to process.
   * @return The result of the command.
   */
  @Override
  public String doCommand(String command) {
    StringTokenizer tokenizer = new StringTokenizer(command);
    List<String> tokens = new ArrayList<String>();

    while (tokenizer.hasMoreTokens()) {
      tokens.add(tokenizer.nextToken());
    }
    
    if (tokens.size() != 2) {
      return this.reportError(PARAMETER_COUNT_ERROR);
    }
    try {
      return this.getFuelTypes(tokens.get(1));
    }
    catch (ResourceNotFoundException ex) {
      return this.reportError(SOURCE_ERROR + tokens.get(1));
    }
    catch (BadXmlException ex) {
      return this.reportError(BAD_XML_ERROR);
    }
    catch (Exception ex) {
      return this.reportError(CONNECTION_ERROR);
    }
  }
  
  /**
   * List all the fuel type information for a given source and its sub-sources.
   * 
   * @param sourceName The name of the source to be summarized.
   * @throws MiscClientException Exception
   * @throws BadXmlException Exception
   * @throws ResourceNotFoundException Exception
   * @throws NotAuthorizedException Exception
   * @return message that contains the fuel type information
   */
  private String getFuelTypes(String sourceName) throws NotAuthorizedException, 
    ResourceNotFoundException, BadXmlException, MiscClientException {
    Source source = client.getSource(sourceName);
    String fuelType = "fuelType";
    String format = " %6s: %s \n";
    StringBuffer buf = new StringBuffer();
    List<Source> nonVirtualSources = new ArrayList<Source>();
    WattDepotCliCommand.getNonVirtualSources(nonVirtualSources, source, client);
    buf.append(String.format(format, "Type", "Source"));
    
    // Group the sources by fuel type.
    Map<String, String> fuelMap = new TreeMap<String, String>();
    for (Source temp : nonVirtualSources) {
      String tempType = temp.getProperty(fuelType);
      String tempName = temp.getName();
      
      if (fuelMap.containsKey(tempType)) {
        fuelMap.put(tempType, fuelMap.get(tempType) + ", " + tempName);
      }
      else {
        fuelMap.put(tempType, tempName);
      }
    }
    
    // Print out the contents.
    for (Entry<String, String> entry : fuelMap.entrySet()) {
      buf.append(String.format(format, entry.getKey(), entry.getValue()));
    }
    
    return buf.toString();
  }
  
  
  /**
   * Gets the help string associated with the fueltypes command.
   * 
   * @see org.wattdepot.cli.command.WattDepotCliCommand#getHelp()
   * @return Information on how to invoke the fueltypes command.
   */
  @Override
  public String getHelp() {
    return "fueltypes {source}\n"
      + "  Prints information about sources generating power using different fuel types.\n";
  }
}
